package com.hdq.aspect;

import com.hdq.annotation.AutoFill;
import com.hdq.annotation.AutoFillList;
import com.hdq.constant.AutoFillConstant;
import com.hdq.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.List;

@Aspect
@Component("autoFillListAspect")
@Slf4j
public class AutoFillListAspect {

    @Pointcut("execution(* com.hdq.mapper.*.*(..)) && @annotation(com.hdq.annotation.AutoFillList)")
    public void autoFillListPointcut() {
    }


    @Before("autoFillListPointcut()")
    public void autoFillList(JoinPoint joinPoint) {
        log.info("运行{}", joinPoint);

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutoFillList annotation = signature.getMethod().getAnnotation(AutoFillList.class);
        OperationType operationType = annotation.value();

        Object[] args = joinPoint.getArgs();
        if (args.length == 0 || args == null) return;

        List<Object> entities =(List<Object>) args[0];

        for (Object entity : entities) {
            LocalDateTime createTime = LocalDateTime.now();
            LocalDateTime updateTime = LocalDateTime.now();
            if (operationType == OperationType.INSERT) {
                try {
                    Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                    Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);

                    setCreateTime.invoke(entity, createTime);
                    setUpdateTime.invoke(entity, updateTime);

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            } else if (operationType == OperationType.UPDATE) {
                try {
                    Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                    setUpdateTime.invoke(entity, updateTime);

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
